#include "project_startup_interface.h"
#include "ui_project_startup_interface.h"
#include <QObject>
#include <QMessageBox>
#include <QCheckBox>
#include "project_startup/prostartup_newpro.h"

project_startup_interface::project_startup_interface(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::project_startup_interface)
{
    ui->setupUi(this);

    Qt::WindowFlags winFlag = Qt::Dialog;
    winFlag |= Qt::WindowMinimizeButtonHint;
    winFlag |= Qt::WindowMaximizeButtonHint;
    winFlag |= Qt::WindowCloseButtonHint;

    setWindowFlags(winFlag);  // 设置右上角窗口按钮

    this->load_proStoreConfig();
    this->check_proStoreConfig();
    this->load_proTree();
}

project_startup_interface::~project_startup_interface()
{
    delete ui;
}

void project_startup_interface::load_proStoreConfig()
{
#ifdef Q_OS_LINUX
    this->proStoreConfig.proStoreFilePath = "/etc/vfeda/";
    this->proStoreConfig.proStoreFileName = "proStoreList.xml";
    this->proStoreConfig.defaultProNewFilePath = "/etc/vfeda/project/";
#endif
#ifdef Q_OS_MACOS
    this->proStoreConfig.proStoreFilePath = "/etc/vfeda/";
    this->proStoreConfig.proStoreFileName = "proStoreList.xml";
    this->proStoreConfig.defaultProNewFilePath = "/etc/vfeda/project/";
#endif
#ifdef Q_OS_WIN
//    this->proStoreConfig.proStoreFilePath = "%appdata%/vfeda/";
    this->proStoreConfig.proStoreFilePath = QDir::fromNativeSeparators(qEnvironmentVariable("appdata")) + "/vfeda/";
    this->proStoreConfig.proStoreFileName = "proStoreList.xml";
    this->proStoreConfig.defaultProNewFilePath = this->proStoreConfig.proStoreFilePath + "project/";


#endif
}

void project_startup_interface::check_proStoreConfig()
{
    // 检测默认工程文件存放路径
    QDir d;
    if (!d.exists(this->proStoreConfig.proStoreFilePath))
    {
        if (!d.mkdir(this->proStoreConfig.proStoreFilePath))
        {
            QMessageBox::warning(this, "Error", "Can't Create vfeda Folder !!!");
            qApp->exit();
        }
    }

    if (!d.exists(this->proStoreConfig.defaultProNewFilePath))
    {
        if (!d.mkdir(this->proStoreConfig.defaultProNewFilePath))
        {
            QMessageBox::warning(this, "Error", "Can't Create Project Folder !!!");
            qApp->exit();
        }
    }
}

void project_startup_interface::load_proTree()
{
    qDebug() << this->proStoreConfig.get_proStoreFile();
    QFile file(this->proStoreConfig.get_proStoreFile());

    if (!file.open(QFile::ReadOnly))
    {
        if (!file.open(QFile::ReadWrite))
        {
            QMessageBox::warning(this, "Error", "Can't Create Project Store File !!!");
            qApp->exit();
        }

        this->init_proStoreFile(&file);
        file.close();
        return;
    }

    QDomDocument doc;
    if (!doc.setContent(&file))
    {
        file.close();
        return;
    }

    QDomElement root = doc.documentElement();

    //QDomNode node = root.firstChild();  // 获取第一个子节点
    QDomNodeList list = root.childNodes();  // 获取子节点列表

    ui->treeWidget->setColumnCount(list.count() + 1);  // 初始化列数

    this->make_proTree(list);

    // 生成TreeWidget头部
    QTreeWidgetItem *headerItem = new QTreeWidgetItem();
    headerItem->setText(0, tr("工程项目"));
    headerItem->setTextAlignment(0, Qt::AlignCenter);
    ui->treeWidget->setHeaderItem(headerItem);

    file.close();
}

void project_startup_interface::init_proStoreFile(QFile *file)
{
    QDomDocument doc;
    QDomProcessingInstruction instruction;  // 命令处理变量

    instruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
    doc.appendChild(instruction);

    QDomElement root = doc.createElement("project_list");
    doc.appendChild(root);

    QTextStream out(file);
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
    out.setCodec("utf-8");
#endif
    doc.save(out, 4);   // 缩减4格并保存
}

void project_startup_interface::make_proTree(QDomNodeList list, QTreeWidgetItem *item)
{
    for (int n(0); n < list.count(); n++) {
        QDomNode node = list.at(n);
        QDomElement element = node.toElement();

        QTreeWidgetItem *childItem = nullptr;
        if (item == nullptr)
            childItem = new QTreeWidgetItem(ui->treeWidget);
        else
            childItem = new QTreeWidgetItem(item);

        if (node.nodeName() == "project_folder")
        {
            QIcon icon(QPixmap(":/image/image/project_floder.png").scaled(25, 25, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));  // 自适应缩放和平滑缩放

            childItem->setIcon(0, icon); //  设置当前item的icon图标为工程文件夹
            childItem->setText(0, element.attribute("name"));

            this->make_proTree(node.childNodes(), childItem);
        }
        else if (node.nodeName() == "project")
        {
            QIcon icon(QPixmap(":/image/image/project_file.jpg").scaled(25, 25, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));  // 自适应缩放和平滑缩放

            childItem->setIcon(0, icon);
            childItem->setText(0, element.attribute("name"));
            Project_Path proPath;
            proPath.proName = element.attribute("name");
            proPath.proFilePath = element.attribute("src");
            this->projectMap.insert(childItem, proPath);
        }
    }
}

void project_startup_interface::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
{
    if (item->childCount() != 0)
        return;

    Map_Dictionary mapDic = this->map_indexOfproPath(item);

    if (mapDic.ret)
    {
        QString fpath = mapDic.path.proFilePath;
        QFile file(fpath);

        if (!file.exists())
        {
            QMessageBox::information(this, "Error", "Not Find Project File, Delete Project Store Node", QMessageBox::Ok);
            this->delete_node(item);
            return;
        }

        Project_Path proPath;
        proPath.proName = mapDic.path.proName;
        proPath.proFilePath = mapDic.path.proFilePath;
        this->interface_exit(proPath);
    }
}

void project_startup_interface::interface_exit(Project_Path proPath)
{
    emit sendProPath(proPath);
    accept();
}

void project_startup_interface::on_pushButton_add_project_clicked()
{
    proStartup_newPro *newPro = new proStartup_newPro(this);
    newPro->setModal(true);
    newPro->set_proNewFilePath(this->proStoreConfig.defaultProNewFilePath);
    newPro->set_rootTreeItem(ui->treeWidget->invisibleRootItem());

    connect(newPro, &proStartup_newPro::sendProjectPath, this, &project_startup_interface::recv_newPro);
    newPro->show();
}

void project_startup_interface::delete_node(QTreeWidgetItem *item, bool judgeDeleteFile)
{
    QTreeWidgetItem *parent = item->parent();
    QList<int> child_node_list;

    Map_Dictionary mapDic = this->map_indexOfproPath(item);


    if (!mapDic.ret)
    {
        QMessageBox::information(this, "Error", "Can't Find QTreeWidgetItem", QMessageBox::Ok);
        return;
    }

    if (parent)
    {
        QTreeWidgetItem *temp_parent = parent;
        QTreeWidgetItem *temp_child = item;

        do
        {
            child_node_list.append(temp_parent->indexOfChild(temp_child));
            temp_child = temp_parent;
            temp_parent = temp_parent->parent();

        } while(temp_parent);

        child_node_list.append(ui->treeWidget->indexOfTopLevelItem(temp_child));

        qDebug() << child_node_list;

        parent->removeChild(item);
    }
    else
    {
        int node = ui->treeWidget->indexOfTopLevelItem(item);
        child_node_list.append(node);
        ui->treeWidget->takeTopLevelItem(node);
    }

    // 工程仓库文件删除节点
    QFile file(this->proStoreConfig.get_proStoreFile());

    if (!file.open(QFile::ReadOnly))
    {
        QMessageBox::information(this, "Error", "Can't Open Project Store File", QMessageBox::Ok);
        this->close();
    }

    QDomDocument doc;
    if (!doc.setContent(&file))
    {
        QMessageBox::information(this, "Error", "Can't Read Project Store File", QMessageBox::Ok);
        file.close();
        this->close();
    }

    file.close();

    QDomElement root = doc.documentElement();

    QDomNodeList list = root.childNodes();

    QDomNode child_node;

    for (int n(child_node_list.count() - 1); n >= 0; n--) {
        child_node = list.at(child_node_list.at(n));
        qDebug() << "child name " << child_node.toElement().attribute("name");
        list = child_node.childNodes();
    }

    QDomNode nodeParent = child_node.parentNode();
    nodeParent.removeChild(child_node);

    if (!file.open(QFile::ReadWrite | QFile::Truncate))
    {
        QMessageBox::information(this, "Error", "Can't Open Project Store File", QMessageBox::Ok);
        this->close();
    }

    QTextStream out(&file);
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
    out.setCodec("utf-8");
#endif
    doc.save(out, 4);
    file.close();

    // 删除工程文件
    if (judgeDeleteFile)
    {
        if (QDir().exists(mapDic.path.proFilePath) && QFile::exists(mapDic.path.proFilePath))
        {
            QFile::remove(mapDic.path.proFilePath);
        }
    }
}

void project_startup_interface::recv_newPro(Project_Path path)
{
    int ret = this->init_proFile(path);
    if (ret)
        return;

    this->add_node(path);

    this->interface_exit(path);
}

int project_startup_interface::init_proFile(Project_Path path)
{
    QDir dir;
    QFileInfo info(path.proFilePath);

    qDebug() << "info" << path.proFilePath;
    if (! dir.exists(info.path()))
    { dir.mkpath(info.path()); }

    qDebug() << "path" << path.proFilePath << path.proName;
    QFile file(path.proFilePath + path.proName);


    if (file.exists())
    {
        QMessageBox::information(this, "提示", "工程文件已存在，无法创建", QMessageBox::Ok);
        return 1;
    }

    if (!file.open(QFile::WriteOnly))
    {
        QMessageBox::information(this, "Error", "Can't Create Project Store File", QMessageBox::Ok);
        return 1;
    }

    QDomDocument doc;
    QDomProcessingInstruction instruction;  // 命令处理变量

    instruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
    doc.appendChild(instruction);

    QDomElement root = doc.createElement("project");

    QDomElement module_table = doc.createElement("module_table");
    root.appendChild(module_table);

    QDomElement port_connexion = doc.createElement("port_connexion");
    root.appendChild(port_connexion);

    QDomElement log = doc.createElement("log");
    root.appendChild(log);

    doc.appendChild(root);

    QTextStream out(&file);
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
    out.setCodec("utf-8");
#endif
    doc.save(out, 4);   // 缩减4格并保存

    file.close();

    return 0;
}

void project_startup_interface::add_node(Project_Path proPath)
{
    QString node = "/";

    QFile file(this->proStoreConfig.get_proStoreFile());
    QDomDocument doc;

    if (!file.open(QFile::ReadOnly))
    {
        QMessageBox::information(this, "Error", "Can't Read Project Store File", QMessageBox::Ok);
        this->close();
    }

    if (!doc.setContent(&file))
    {
        QMessageBox::information(this, "Error", "Can't Read Project Store File", QMessageBox::Ok);
        file.close();
        this->close();
    }

    file.close();

    QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeWidget);
    item->setText(0, proPath.proName);

    this->projectMap.insert(item, proPath);

    if (node == "/")
    {
        QDomElement root = doc.documentElement();

        QDomElement newPro = doc.createElement("project");
        newPro.setAttribute("name", proPath.proName);
        newPro.setAttribute("src", proPath.proFilePath);

        root.appendChild(newPro);
    }
    else
    {
        ;;
    }

    if (!file.open(QFile::ReadWrite | QFile::Truncate))
    {
        QMessageBox::information(this, "Error", "Can't Write Project Store File", QMessageBox::Ok);
        this->close();
    }

    QTextStream out(&file);
#if (QT_VERSION < QT_VERSION_CHECK(6,0,0))
    out.setCodec("utf-8");
#endif
    doc.save(out, 4);
    file.close();
}

void project_startup_interface::on_pushButton_deletePro_clicked()
{
    QTreeWidgetItem *item = ui->treeWidget->currentItem();

    if (item)
    {
        if (item->childCount())
        {
            QMessageBox::information(this, "Error", "不能够删除工程文件夹，需要工程文件夹为空才能删除!!!", QMessageBox::Ok);
        }
        else
        {
            QCheckBox *cb = new QCheckBox("是否删除工程源文件？");
            QMessageBox box;
            QAbstractButton *yesButton = (QAbstractButton *)box.addButton(QMessageBox::Yes);
            QAbstractButton *noButton = (QAbstractButton *)box.addButton(QMessageBox::No);

            box.setText("是否删除此工程？");
            box.setDefaultButton(QMessageBox::No);
            box.setCheckBox(cb);

            this->delFileCheck = false;

            QObject::connect(cb, &QCheckBox::stateChanged, [this](int state) {
                if (static_cast<Qt::CheckState>(state) == Qt::CheckState::Checked)
                {
                    this->delFileCheck = true;
                }
            });

            box.exec();

            if (yesButton == box.clickedButton())
            {
                if (this->delFileCheck)  // 勾选了
                    this->delete_node(item, true);
                else                    // 未勾选
                    this->delete_node(item);
            }
        }
    }
}

Map_Dictionary project_startup_interface::map_indexOfproPath(QTreeWidgetItem *item)
{
    Map_Dictionary mapDic;
    QMap<QTreeWidgetItem *, Project_Path>::iterator i;  // projectMap迭代器

    i = projectMap.find(item);

    if (i != projectMap.end())
    {
        mapDic.ret = true;
        mapDic.path = i.value();
        return mapDic;
    }

    mapDic.ret = false;
    return mapDic;
}

ProStoreFolderPath project_startup_interface::get_proStoreFolderPath(QTreeWidgetItem *root)
{
    ProStoreFolderPath path;

    for (int rootChildNum(0); rootChildNum < root->childCount(); rootChildNum++) {
        ProStoreFolder folder;
        QString folderName = root->child(rootChildNum)->text(0);

        folder.insert(rootChildNum, folderName);

        FolderPath folderPath;
        folderPath.append("/");

        folderPath.append(project_startup_interface::get_folderPath(root->child(rootChildNum)));

//        qDebug() << folder << folderPath;

        path.insert(&folder, folderPath);
    }

    return path;
}

FolderPath project_startup_interface::get_folderPath(QTreeWidgetItem *folder)
{
    FolderPath path;

    for (int childNum(0); childNum < folder->childCount(); childNum++) {
        QTreeWidgetItem *child = folder->child(childNum);

        if (child->childCount() == 0)
            continue;

        QString name = child->text(0);

        path.append(name);

        path.append(get_folderPath(child));
    }

    return path;
}


void project_startup_interface::on_pushButton_importPro_clicked()
{
    QString file_path = QFileDialog::getOpenFileName(this, "请选择一个工程文件", "./", "工程文件(*.pro)");

    if (file_path.isEmpty() || file_path.isNull())
        return;

    QFileInfo info(file_path);
    Project_Path path;

    path.proFilePath = file_path;
    path.proName = info.fileName().split(".")[0];

    // 检测Path是否存在
    //..........

    this->add_node(path);

//    this->interface_exit(path);
}

